package cn.stylefeng.guns.modular.history.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateException;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.guns.modular.history.entity.VoteHistory;
import cn.stylefeng.guns.modular.history.enums.VoteHistoryExceptionEnum;
import cn.stylefeng.guns.modular.history.pojo.request.VoteHistoryRequest;
import cn.stylefeng.guns.modular.history.service.VoteHistoryService;
import cn.stylefeng.guns.modular.vote.entity.Works;
import cn.stylefeng.guns.modular.vote.enums.WorksExceptionEnum;
import cn.stylefeng.guns.modular.vote.service.WorksService;
import cn.stylefeng.roses.kernel.scanner.api.annotation.ApiResource;
import cn.stylefeng.roses.kernel.scanner.api.annotation.GetResource;
import cn.stylefeng.roses.kernel.scanner.api.annotation.PostResource;
import cn.stylefeng.roses.kernel.system.api.constants.SystemConstants;
import cn.stylefeng.roses.kernel.system.modular.organization.entity.HrOrganization;
import cn.stylefeng.roses.kernel.config.api.context.ConfigContext;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import cn.stylefeng.roses.kernel.file.api.expander.FileConfigExpander;
import cn.stylefeng.roses.kernel.file.modular.entity.SysFileInfo;
import cn.stylefeng.roses.kernel.rule.pojo.response.ErrorResponseData;
import cn.stylefeng.roses.kernel.rule.pojo.response.ResponseData;
import cn.stylefeng.roses.kernel.rule.pojo.response.SuccessResponseData;
import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil;

import org.apache.commons.net.util.SubnetUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gettyio.core.util.StringUtil;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * 投票记录表;控制器
 *
 * @author songq
 * @date 2025/04/22 14:55
 */
@RestController
@ApiResource(name = "投票记录表;")
public class VoteHistoryController {

    @Resource
    private VoteHistoryService voteHistoryService;
    
    @Resource
    private WorksService worksService;
    
    /**
     * 投票
     *
     * @author songq
     * @date 2025/04/22 14:55
     */
    @PostResource(name = "添加", path = "/voteHistory/add")
    public ResponseData<VoteHistory> add(@RequestBody @Validated(VoteHistoryRequest.add.class) VoteHistoryRequest voteHistoryRequest) {
        voteHistoryService.add(voteHistoryRequest);
        return new SuccessResponseData<>();
    }

    /**
     * 投票
     *
     * @author songq
     * @date 2025/04/22 14:55
     */
    @PostResource(name = "投票", path = "/voteHistory/vote")
    public synchronized ResponseData<VoteHistory> vote(@RequestBody Long[] ids) {
    	//获取投票开始结束时间
    	String begin = ConfigContext.me().getSysConfigValueWithDefault("VOTE_BEGIN_TIME", String.class, "");
    	String end = ConfigContext.me().getSysConfigValueWithDefault("VOTE_END_TIME", String.class, "");
    	Date voteBegin;
    	Date voteEnd;
    	Date now = new Date();
    	try {
    		voteBegin = DateUtil.parse(begin);
    		voteEnd = DateUtil.parse(end);
    		//投票是否开始
    		if(now.before(voteBegin)) {
    			return new ErrorResponseData<>(VoteHistoryExceptionEnum.VOTE_NOT_BEGIN.getErrorCode(),
    					VoteHistoryExceptionEnum.VOTE_NOT_BEGIN.getUserTip());
    		}
    		if(now.after(voteEnd)) {
    			return new ErrorResponseData<>(VoteHistoryExceptionEnum.VOTE_END.getErrorCode(),
    					VoteHistoryExceptionEnum.VOTE_END.getUserTip());
    		}
    		//查询作品
    		if(ids == null || ids.length == 0) {
    			return new ErrorResponseData<>(WorksExceptionEnum.WORKS_PARAM_IGNOR.getErrorCode(),
        				WorksExceptionEnum.WORKS_PARAM_IGNOR.getUserTip());
    		}
    		//ip是否允许
        	String voteIp = getRealIp(HttpServletUtil.getRequest());
        	String voteClient = HttpServletUtil.getRequest().getHeader("User-Agent");
        	if(StringUtil.isEmpty(voteIp)) {
        		return new ErrorResponseData<>(VoteHistoryExceptionEnum.VOTE_IP_NOTEXIST.getErrorCode(),
    					VoteHistoryExceptionEnum.VOTE_IP_NOTEXIST.getUserTip());
        	}
        	// 1. 检查临时白名单和网段是否允许投票
        	try {
        		String allowIpProp = ConfigContext.me().getConfigValue("VOTE_ALLOW_IPS", String.class);
        		String[] allows = allowIpProp.split(",");
        		List<String> whiteList = CollectionUtil.list(true, allows);
				boolean ipcheck = IpValidatorUtil.checkIpAccess(voteIp, whiteList);
				if(!ipcheck) {
					return new ErrorResponseData<>(VoteHistoryExceptionEnum.VOTE_NOT_ALLOW_IP.getErrorCode(),
							VoteHistoryExceptionEnum.VOTE_NOT_ALLOW_IP.getUserTip());
				}
			} catch (Exception e) {
				// TODO: handle exception
        		return new ErrorResponseData<>(VoteHistoryExceptionEnum.VOTE_IP_NOTEXIST.getErrorCode(),
    					"投票ip有效性检查错误，请联系管理员");
			}
        	
        	//ip是否已经投票
        	LambdaQueryWrapper<VoteHistory> wrapper = new LambdaQueryWrapper<>();
        	wrapper.eq(VoteHistory::getVoteIp, voteIp);
        	List<VoteHistory> voteList = voteHistoryService.list(wrapper);
        	if(CollectionUtil.isNotEmpty(voteList)) {
        		return new ErrorResponseData<>(VoteHistoryExceptionEnum.VOTE_IP_EXIT.getErrorCode(),
    					VoteHistoryExceptionEnum.VOTE_IP_EXIT.getUserTip());
        	}
        	//校验作品是否存在
        	LambdaQueryWrapper<Works> workwrapper = new LambdaQueryWrapper<>();
        	workwrapper.in(Works::getWorkId, ids);
        	List<Works> workList = worksService.list(workwrapper);
        	if(CollectionUtil.isEmpty(workList) || ids.length != workList.size()) {
    			return new ErrorResponseData<>(WorksExceptionEnum.WORKS_NOT_EXISTED.getErrorCode(),
        				WorksExceptionEnum.WORKS_NOT_EXISTED.getUserTip());
    		}
        	
        	
        	//校验全部通过开始投票
        	VoteHistoryRequest voteHistoryRequest = new VoteHistoryRequest();
        	voteHistoryRequest.setVoteIp(voteIp);
        	voteHistoryRequest.setVoteClient(voteClient);
        	voteHistoryService.vote(voteHistoryRequest,workList);
        	return new SuccessResponseData<>();
    		
		} catch (DateException e) {
			return new ErrorResponseData<>(VoteHistoryExceptionEnum.VOTE_TIME_NOT_EXISTED.getErrorCode(),
					VoteHistoryExceptionEnum.VOTE_TIME_NOT_EXISTED.getUserTip());
		} catch (Exception e) {
			// TODO: handle exception
			return new ErrorResponseData<>(VoteHistoryExceptionEnum.VOTE_UNKNOW_ERROR.getErrorCode(),
					VoteHistoryExceptionEnum.VOTE_UNKNOW_ERROR.getUserTip());
		}
        
    }
    // 获取ip
    private String getRealIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip.split(",")[0].trim(); // 处理多级代理
    }

    /**
     * 删除
     *
     * @author songq
     * @date 2025/04/22 14:55
     */
    @PostResource(name = "删除", path = "/voteHistory/delete")
    public ResponseData<?> delete(@RequestBody @Validated(VoteHistoryRequest.delete.class) VoteHistoryRequest voteHistoryRequest) {
        voteHistoryService.del(voteHistoryRequest);
        return new SuccessResponseData<>();
    }

    /**
     * 编辑
     *
     * @author songq
     * @date 2025/04/22 14:55
     */
    @PostResource(name = "编辑", path = "/voteHistory/edit")
    public ResponseData<?> edit(@RequestBody @Validated(VoteHistoryRequest.edit.class) VoteHistoryRequest voteHistoryRequest) {
        voteHistoryService.edit(voteHistoryRequest);
        return new SuccessResponseData<>();
    }

    /**
     * 查看详情
     *
     * @author songq
     * @date 2025/04/22 14:55
     */
    @GetResource(name = "查看详情", path = "/voteHistory/detail")
    public ResponseData<VoteHistory> detail(@Validated(VoteHistoryRequest.detail.class) VoteHistoryRequest voteHistoryRequest) {
        return new SuccessResponseData<>(voteHistoryService.detail(voteHistoryRequest));
    }

    /**
     * 获取列表
     *
     * @author songq
     * @date 2025/04/22 14:55
     */
    @GetResource(name = "获取列表", path = "/voteHistory/list")
    public ResponseData<List<VoteHistory>> list(VoteHistoryRequest voteHistoryRequest) {
        return new SuccessResponseData<>(voteHistoryService.findList(voteHistoryRequest));
    }

    /**
     * 获取列表（带分页）
     *
     * @author songq
     * @date 2025/04/22 14:55
     */
    @GetResource(name = "分页查询", path = "/voteHistory/page")
    public ResponseData<PageResult<VoteHistory>> page(VoteHistoryRequest voteHistoryRequest) {
    	PageResult<VoteHistory> vhiss = voteHistoryService.findPage(voteHistoryRequest);
    	List<VoteHistory>  vhisworksResults = new ArrayList<VoteHistory>();
    	for(VoteHistory his : vhiss.getRows()) {
    		VoteHistory v = new VoteHistory();
    		BeanUtil.copyProperties(his, v);
    		if(BeanUtil.isNotEmpty(v.getWorkId())) {
    			Works w = worksService.getById(v.getWorkId());
    			if(BeanUtil.isNotEmpty(w,"") ) {
    				v.setWorkName(w.getWorkAuthor() + "(" + w.getWorkTitle() + ")");
    			}
    		}
    		vhisworksResults.add(v);
    	}
    	vhiss.setRows(vhisworksResults);
        return new SuccessResponseData<>(vhiss);
    }

}
